//
//  XMPPDataSecurity.m
//  Messenger
//
//  Created by OC on 15/11/3.
//  Copyright (c) 2015年 李健. All rights reserved.
//
//  数据加密处理类
//

#define YN_MESSENGER_OA_KEY @"nedutkey"


#import "XMPPDataSecurity.h"
#import "YNIMFrameworkMacro.h"
#import "GTMBase64.h"
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCrypto.h>
#import "YNIMTool.h"

@implementation XMPPDataSecurity

+(NSString *)dataEncryptionBy:(NSString*)orgData{
    NSString*resultStr=@"";
    if (![YNIMTool isEmptyString:orgData]) {
       resultStr= [self encryptUseDES:orgData key:@"oijowcwwefn"];
    }
    return resultStr;
}

+(NSString *)dataDecryptionBy:(NSString*)secretData{
    NSString*resultStr=@"";
    if (![YNIMTool isEmptyString:secretData]) {
        resultStr=[self decryptUseDES:secretData key:@"oijowcwwefn"];
    }
    return resultStr;
}

+(NSString *)encryptUseDES:(NSString *)orgText key:(NSString *)key
{
    NSString *ciphertext = nil;
    NSString*plainText= [orgText stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    const char *textBytes = [plainText UTF8String];
    NSUInteger dataLength = [plainText length];
    unsigned char buffer[1024];
    memset(buffer, 0, sizeof(char));
    NSString * final =[XMPPDataSecurity md5String:key];
    final= [final uppercaseString];
    final =[final substringWithRange:NSMakeRange(0, 8)];
    char * keyChar =(char*)[final UTF8String];
    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,
                                          kCCOptionPKCS7Padding,
                                          keyChar, kCCKeySizeDES,
                                          keyChar,
                                          textBytes, dataLength,
                                          buffer, 1024,
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
        
        ciphertext =[self convertDataToHexStr:data];
        ciphertext =[ciphertext uppercaseString];
    }
    return ciphertext;
}
//解密
+(NSString *)decryptUseDES:(NSString*)cipherText key:(NSString*)key
{
    NSData* cipherData =[self convertHexStrToData:cipherText];
    unsigned char buffer[1024];
    memset(buffer, 0, sizeof(char));
    size_t numBytesDecrypted = 0;
    NSString * final =[self md5String:key];
    final= [final uppercaseString];
    final =[final substringWithRange:NSMakeRange(0, 8)];
    char * keyChar =(char*)[final UTF8String];
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          kCCAlgorithmDES,
                                          kCCOptionPKCS7Padding,
                                          keyChar,
                                          kCCKeySizeDES,
                                          keyChar,
                                          [cipherData bytes],
                                          [cipherData length],
                                          buffer,
                                          1024,
                                          &numBytesDecrypted);
    NSString* plainText = nil;
    if (cryptStatus == kCCSuccess) {
        NSData* data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesDecrypted];
        plainText = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        plainText = [plainText stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    }
    return plainText;
}
+(NSString *)md5String:(NSString *)sourceString{
    if(!sourceString){
        return nil;//判断sourceString如果为空则直接返回nil。
    }
    //MD5加密都是通过C级别的函数来计算，所以需要将加密的字符串转换为C语言的字符串
    const char *cString = sourceString.UTF8String;
    //创建一个C语言的字符数组，用来接收加密结束之后的字符
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    //MD5计算（也就是加密）
    //第一个参数：需要加密的字符串
    //第二个参数：需要加密的字符串的长度
    //第三个参数：加密完成之后的字符串存储的地方
    CC_MD5(cString, (CC_LONG)strlen(cString), result);
    //将加密完成的字符拼接起来使用（16进制的）。
    //声明一个可变字符串类型，用来拼接转换好的字符
    NSMutableString *resultString = [[NSMutableString alloc]init];
    //遍历所有的result数组，取出所有的字符来拼接
    for (int i = 0;i < CC_MD5_DIGEST_LENGTH; i++) {
        [resultString  appendFormat:@"%02x",result[i]];
        //%02x：x 表示以十六进制形式输出，02 表示不足两位，前面补0输出；超出两位，不影响。当x小写的时候，返回的密文中的字母就是小写的，当X大写的时候返回的密文中的字母是大写的。
    }
    
    return resultString;
}

//将NSData转成16进制
+ (NSString *)convertDataToHexStr:(NSData *)data {
    if (!data || [data length] == 0) {
        return @"";
    }
    NSMutableString *string = [[NSMutableString alloc] initWithCapacity:[data length]];
    
    [data enumerateByteRangesUsingBlock:^(const void *bytes, NSRange byteRange, BOOL *stop) {
        unsigned char *dataBytes = (unsigned char*)bytes;
        for (NSInteger i = 0; i < byteRange.length; i++) {
            NSString *hexStr = [NSString stringWithFormat:@"%x", (dataBytes[i]) & 0xff];
            if ([hexStr length] == 2) {
                [string appendString:hexStr];
            } else {
                [string appendFormat:@"0%@", hexStr];
            }
        }
    }];
    return string;
}
//将16进制字符串转成NSData
+ (NSData *)convertHexStrToData:(NSString *)str {
    if (!str || [str length] == 0) {
        return nil;
    }
    
    NSMutableData *hexData = [[NSMutableData alloc] initWithCapacity:8];
    NSRange range;
    if ([str length] % 2 == 0) {
        range = NSMakeRange(0, 2);
    } else {
        range = NSMakeRange(0, 1);
    }
    for (NSInteger i = range.location; i < [str length]; i += 2) {
        unsigned int anInt;
        NSString *hexCharStr = [str substringWithRange:range];
        NSScanner *scanner = [[NSScanner alloc] initWithString:hexCharStr];
        
        [scanner scanHexInt:&anInt];
        NSData *entity = [[NSData alloc] initWithBytes:&anInt length:1];
        [hexData appendData:entity];
        
        range.location += range.length;
        range.length = 2;
    }
    return hexData;
}






//DES 加密 key秘钥
+ (NSString *)encryptUseDES:(NSString *)clearText key:(NSString *)key andiv:(NSString *)iv
{
    //这个iv 是DES加密的初始化向量，可以用和密钥一样的MD5字符
    NSData * data = [iv dataUsingEncoding:NSUTF8StringEncoding];
    NSString *ciphertext = nil;
    NSUInteger dataLength = [clearText length];
    NSData *textData = [clearText dataUsingEncoding:NSUTF8StringEncoding];
    
    unsigned char buffer[1024];
    memset(buffer, 0, sizeof(char));
    size_t numBytesEncrypted = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,//加密模式 kCCDecrypt 代表解密
                                          kCCAlgorithmDES,//加密方式
                                          kCCOptionPKCS7Padding,//填充算法
                                          [key UTF8String], //密钥字符串
                                          kCCKeySizeDES,//加密位数
                                          [data bytes],//初始化向量
                                          [textData bytes]  ,
                                          dataLength,
                                          buffer, 1024,
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        debugLog(@"DES加密成功")
        NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
        ciphertext = [[NSString alloc] initWithData:[GTMBase64 encodeData:data] encoding:NSUTF8StringEncoding];
        
    }else{
        
        debugLog(@"DES加密失败")
    }
    return ciphertext;
}

@end
